/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
 */

#ifndef __CORESIGHT_H
#define __CORESIGHT_H

#include <asm/local.h>
#include <linux/types.h>

/*
 * Device registers:
 * 0x000 - 0x2FC: Trace		registers
 * 0x300 - 0x314: Management	registers
 * 0x318 - 0xEFC: Trace		registers
 * 0xF00: Management		registers
 * 0xFA0 - 0xFA4: Trace		registers
 * 0xFA8 - 0xFFC: Management	registers
 */
/* Trace registers (0x000-0x2FC) */
/* Main control and configuration registers */
#define TRCPRGCTLR 0x004
#define TRCPROCSELR 0x008
#define TRCSTATR 0x00C
#define TRCCONFIGR 0x010
#define TRCAUXCTLR 0x018
#define TRCEVENTCTL0R 0x020
#define TRCEVENTCTL1R 0x024
#define TRCRSR 0x028
#define TRCSTALLCTLR 0x02C
#define TRCTSCTLR 0x030
#define TRCSYNCPR 0x034
#define TRCCCCTLR 0x038
#define TRCBBCTLR 0x03C
#define TRCTRACEIDR 0x040
#define TRCQCTLR 0x044
/* Filtering control registers */
#define TRCVICTLR 0x080
#define TRCVIIECTLR 0x084
#define TRCVISSCTLR 0x088
#define TRCVIPCSSCTLR 0x08C
/* Derived resources registers */
#define TRCSEQEVRn(n) (0x100 + (n * 4)) /* n = 0-2 */
#define TRCSEQRSTEVR 0x118
#define TRCSEQSTR 0x11C
#define TRCEXTINSELR 0x120
#define TRCEXTINSELRn(n) (0x120 + (n * 4)) /* n = 0-3 */
#define TRCCNTRLDVRn(n) (0x140 + (n * 4)) /* n = 0-3 */
#define TRCCNTCTLRn(n) (0x150 + (n * 4)) /* n = 0-3 */
#define TRCCNTVRn(n) (0x160 + (n * 4)) /* n = 0-3 */
/* ID registers */
#define TRCIDR8 0x180
#define TRCIDR9 0x184
#define TRCIDR10 0x188
#define TRCIDR11 0x18C
#define TRCIDR12 0x190
#define TRCIDR13 0x194
#define TRCIMSPEC0 0x1C0
#define TRCIMSPECn(n) (0x1C0 + (n * 4)) /* n = 1-7 */
#define TRCIDR0 0x1E0
#define TRCIDR1 0x1E4
#define TRCIDR2 0x1E8
#define TRCIDR3 0x1EC
#define TRCIDR4 0x1F0
#define TRCIDR5 0x1F4
#define TRCIDR6 0x1F8
#define TRCIDR7 0x1FC
/*
 * Resource selection registers, n = 2-31.
 * First pair (regs 0, 1) is always present and is reserved.
 */
#define TRCRSCTLRn(n) (0x200 + (n * 4))
/* Single-shot comparator registers, n = 0-7 */
#define TRCSSCCRn(n) (0x280 + (n * 4))
#define TRCSSCSRn(n) (0x2A0 + (n * 4))
#define TRCSSPCICRn(n) (0x2C0 + (n * 4))
/* Management registers (0x300-0x314) */
#define TRCOSLAR 0x300
#define TRCOSLSR 0x304
#define TRCPDCR 0x310
#define TRCPDSR 0x314
/* Trace registers (0x318-0xEFC) */
/* Address Comparator registers n = 0-15 */
#define TRCACVRn(n) (0x400 + (n * 8))
#define TRCACATRn(n) (0x480 + (n * 8))
/* ContextID/Virtual ContextID comparators, n = 0-7 */
#define TRCCIDCVRn(n) (0x600 + (n * 8))
#define TRCVMIDCVRn(n) (0x640 + (n * 8))
#define TRCCIDCCTLR0 0x680
#define TRCCIDCCTLR1 0x684
#define TRCVMIDCCTLR0 0x688
#define TRCVMIDCCTLR1 0x68C
/* Management register (0xF00) */
/* Integration control registers */
#define TRCITCTRL 0xF00
/* Trace registers (0xFA0-0xFA4) */
/* Claim tag registers */
#define TRCCLAIMSET 0xFA0
#define TRCCLAIMCLR 0xFA4
/* Management registers (0xFA8-0xFFC) */
#define TRCDEVAFF0 0xFA8
#define TRCDEVAFF1 0xFAC
#define TRCLAR 0xFB0
#define TRCLSR 0xFB4
#define TRCAUTHSTATUS 0xFB8
#define TRCDEVARCH 0xFBC
#define TRCDEVID 0xFC8
#define TRCDEVTYPE 0xFCC
#define TRCPIDR4 0xFD0
#define TRCPIDR5 0xFD4
#define TRCPIDR6 0xFD8
#define TRCPIDR7 0xFDC
#define TRCPIDR0 0xFE0
#define TRCPIDR1 0xFE4
#define TRCPIDR2 0xFE8
#define TRCPIDR3 0xFEC
#define TRCCIDR0 0xFF0
#define TRCCIDR1 0xFF4
#define TRCCIDR2 0xFF8
#define TRCCIDR3 0xFFC

#define TRCRSR_TA BIT(12)

/*
 * Bit positions of registers that are defined above, in the sysreg.h style
 * of _MASK for multi bit fields and BIT() for single bits.
 */
#define TRCIDR0_INSTP0_MASK GENMASK(2, 1)
#define TRCIDR0_TRCBB BIT(5)
#define TRCIDR0_TRCCOND BIT(6)
#define TRCIDR0_TRCCCI BIT(7)
#define TRCIDR0_RETSTACK BIT(9)
#define TRCIDR0_NUMEVENT_MASK GENMASK(11, 10)
#define TRCIDR0_QFILT BIT(14)
#define TRCIDR0_QSUPP_MASK GENMASK(16, 15)
#define TRCIDR0_TSSIZE_MASK GENMASK(28, 24)

#define TRCIDR2_CIDSIZE_MASK GENMASK(9, 5)
#define TRCIDR2_VMIDSIZE_MASK GENMASK(14, 10)
#define TRCIDR2_CCSIZE_MASK GENMASK(28, 25)

#define TRCIDR3_CCITMIN_MASK GENMASK(11, 0)
#define TRCIDR3_EXLEVEL_S_MASK GENMASK(19, 16)
#define TRCIDR3_EXLEVEL_NS_MASK GENMASK(23, 20)
#define TRCIDR3_TRCERR BIT(24)
#define TRCIDR3_SYNCPR BIT(25)
#define TRCIDR3_STALLCTL BIT(26)
#define TRCIDR3_SYSSTALL BIT(27)
#define TRCIDR3_NUMPROC_LO_MASK GENMASK(30, 28)
#define TRCIDR3_NUMPROC_HI_MASK GENMASK(13, 12)
#define TRCIDR3_NOOVERFLOW BIT(31)

#define TRCIDR4_NUMACPAIRS_MASK GENMASK(3, 0)
#define TRCIDR4_NUMPC_MASK GENMASK(15, 12)
#define TRCIDR4_NUMRSPAIR_MASK GENMASK(19, 16)
#define TRCIDR4_NUMSSCC_MASK GENMASK(23, 20)
#define TRCIDR4_NUMCIDC_MASK GENMASK(27, 24)
#define TRCIDR4_NUMVMIDC_MASK GENMASK(31, 28)

#define TRCIDR5_NUMEXTIN_MASK GENMASK(8, 0)
#define TRCIDR5_TRACEIDSIZE_MASK GENMASK(21, 16)
#define TRCIDR5_ATBTRIG BIT(22)
#define TRCIDR5_LPOVERRIDE BIT(23)
#define TRCIDR5_NUMSEQSTATE_MASK GENMASK(27, 25)
#define TRCIDR5_NUMCNTR_MASK GENMASK(30, 28)

#define TRCCONFIGR_INSTP0_LOAD BIT(1)
#define TRCCONFIGR_INSTP0_STORE BIT(2)
#define TRCCONFIGR_INSTP0_LOAD_STORE \
	(TRCCONFIGR_INSTP0_LOAD | TRCCONFIGR_INSTP0_STORE)
#define TRCCONFIGR_BB BIT(3)
#define TRCCONFIGR_CCI BIT(4)
#define TRCCONFIGR_CID BIT(6)
#define TRCCONFIGR_VMID BIT(7)
#define TRCCONFIGR_COND_MASK GENMASK(10, 8)
#define TRCCONFIGR_TS BIT(11)
#define TRCCONFIGR_RS BIT(12)
#define TRCCONFIGR_QE_W_COUNTS BIT(13)
#define TRCCONFIGR_QE_WO_COUNTS BIT(14)
#define TRCCONFIGR_VMIDOPT BIT(15)
#define TRCCONFIGR_DA BIT(16)
#define TRCCONFIGR_DV BIT(17)

#define TRCEVENTCTL1R_INSTEN_MASK GENMASK(3, 0)
#define TRCEVENTCTL1R_INSTEN_0 BIT(0)
#define TRCEVENTCTL1R_INSTEN_1 BIT(1)
#define TRCEVENTCTL1R_INSTEN_2 BIT(2)
#define TRCEVENTCTL1R_INSTEN_3 BIT(3)
#define TRCEVENTCTL1R_ATB BIT(11)
#define TRCEVENTCTL1R_LPOVERRIDE BIT(12)

#define TRCSTALLCTLR_ISTALL BIT(8)
#define TRCSTALLCTLR_INSTPRIORITY BIT(10)
#define TRCSTALLCTLR_NOOVERFLOW BIT(13)

#define TRCVICTLR_EVENT_MASK GENMASK(7, 0)
#define TRCVICTLR_SSSTATUS BIT(9)
#define TRCVICTLR_TRCRESET BIT(10)
#define TRCVICTLR_TRCERR BIT(11)
#define TRCVICTLR_EXLEVEL_MASK GENMASK(22, 16)
#define TRCVICTLR_EXLEVEL_S_MASK GENMASK(19, 16)
#define TRCVICTLR_EXLEVEL_NS_MASK GENMASK(22, 20)

#define TRCACATRn_TYPE_MASK GENMASK(1, 0)
#define TRCACATRn_CONTEXTTYPE_MASK GENMASK(3, 2)
#define TRCACATRn_CONTEXTTYPE_CTXID BIT(2)
#define TRCACATRn_CONTEXTTYPE_VMID BIT(3)
#define TRCACATRn_CONTEXT_MASK GENMASK(6, 4)
#define TRCACATRn_EXLEVEL_MASK GENMASK(14, 8)

#define TRCSSCSRn_STATUS BIT(31)
#define TRCSSCCRn_SAC_ARC_RST_MASK GENMASK(24, 0)

#define TRCSSPCICRn_PC_MASK GENMASK(7, 0)

#define TRCBBCTLR_MODE BIT(8)
#define TRCBBCTLR_RANGE_MASK GENMASK(7, 0)

#define TRCRSCTLRn_PAIRINV BIT(21)
#define TRCRSCTLRn_INV BIT(20)
#define TRCRSCTLRn_GROUP_MASK GENMASK(19, 16)
#define TRCRSCTLRn_SELECT_MASK GENMASK(15, 0)

/*
 * System instructions to access ETM registers.
 * See ETMv4.4 spec ARM IHI0064F section 4.3.6 System instructions
 */
#define ETM4x_OFFSET_TO_REG(x) ((x) >> 2)

#define ETM4x_CRn(n) (((n) >> 7) & 0x7)
#define ETM4x_Op2(n) (((n) >> 4) & 0x7)
#define ETM4x_CRm(n) ((n) & 0xf)

#include <asm/sysreg.h>
#define ETM4x_REG_NUM_TO_SYSREG(n) \
	sys_reg(2, 1, ETM4x_CRn(n), ETM4x_CRm(n), ETM4x_Op2(n))

#define READ_ETM4x_REG(reg) read_sysreg_s(ETM4x_REG_NUM_TO_SYSREG((reg)))
#define WRITE_ETM4x_REG(val, reg) \
	write_sysreg_s(val, ETM4x_REG_NUM_TO_SYSREG((reg)))

#define read_etm4x_sysreg_const_offset(offset) \
	READ_ETM4x_REG(ETM4x_OFFSET_TO_REG(offset))

#define write_etm4x_sysreg_const_offset(val, offset) \
	WRITE_ETM4x_REG(val, ETM4x_OFFSET_TO_REG(offset))

#define read_ete_sysreg(offset)                                        \
	read_etm4x_sysreg_const_offset(offset);                        \
	if (DEBUG) {                                                   \
		int ete_reg = ETM4x_OFFSET_TO_REG(offset);             \
		pr_err("read_ete_sysreg: 0x%x (%d, %d, %d)\n", offset, \
		       ETM4x_CRn(ete_reg), ETM4x_CRm(ete_reg),         \
		       ETM4x_Op2(ete_reg));                            \
	}

#define write_ete_sysreg(val, offset)                                    \
	if (DEBUG) {                                                     \
		int ete_reg = ETM4x_OFFSET_TO_REG(offset);               \
		pr_err("write_ete_sysreg: 0x%llx-->0x%x (%d, %d, %d)\n", \
		       (u64)(val), offset, ETM4x_CRn(ete_reg),           \
		       ETM4x_CRm(ete_reg), ETM4x_Op2(ete_reg));          \
	}                                                                \
	write_etm4x_sysreg_const_offset(val, offset)

/* ETMv4 resources */
#define ETM_MAX_NR_PE 8
#define ETMv4_MAX_CNTR 4
#define ETM_MAX_SEQ_STATES 4
#define ETM_MAX_EXT_INP_SEL 4
#define ETM_MAX_EXT_INP 256
#define ETM_MAX_EXT_OUT 4
#define ETM_MAX_SINGLE_ADDR_CMP 16
#define ETM_MAX_ADDR_RANGE_CMP (ETM_MAX_SINGLE_ADDR_CMP / 2)
#define ETM_MAX_DATA_VAL_CMP 8
#define ETMv4_MAX_CTXID_CMP 8
#define ETM_MAX_VMID_CMP 8
#define ETM_MAX_PE_CMP 8
#define ETM_MAX_RES_SEL 32
#define ETM_MAX_SS_CMP 8

#define ETMv4_SYNC_MASK 0x1F
#define ETM_CYC_THRESHOLD_MASK 0xFFF
#define ETM_CYC_THRESHOLD_DEFAULT 0x100
#define ETMv4_EVENT_MASK 0xFF
#define ETM_CNTR_MAX_VAL 0xFFFF
#define ETM_TRACEID_MASK 0x3f

#define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb)
/* ETMv4 programming modes */
#define ETM_MODE_EXCLUDE BIT(0)
#define ETM_MODE_LOAD BIT(1)
#define ETM_MODE_STORE BIT(2)
#define ETM_MODE_LOAD_STORE BIT(3)
#define ETM_MODE_BB BIT(4)
#define ETMv4_MODE_CYCACC BIT(5)
#define ETMv4_MODE_CTXID BIT(6)
#define ETM_MODE_VMID BIT(7)
#define ETM_MODE_COND(val) BMVAL(val, 8, 10)
#define ETMv4_MODE_TIMESTAMP BIT(11)
#define ETM_MODE_RETURNSTACK BIT(12)
#define ETM_MODE_QELEM(val) BMVAL(val, 13, 14)
#define ETM_MODE_DATA_TRACE_ADDR BIT(15)
#define ETM_MODE_DATA_TRACE_VAL BIT(16)
#define ETM_MODE_ISTALL BIT(17)
#define ETM_MODE_DSTALL BIT(18)
#define ETM_MODE_ATB_TRIGGER BIT(19)
#define ETM_MODE_LPOVERRIDE BIT(20)
#define ETM_MODE_ISTALL_EN BIT(21)
#define ETM_MODE_DSTALL_EN BIT(22)
#define ETM_MODE_INSTPRIO BIT(23)
#define ETM_MODE_NOOVERFLOW BIT(24)
#define ETM_MODE_TRACE_RESET BIT(25)
#define ETM_MODE_TRACE_ERR BIT(26)
#define ETM_MODE_VIEWINST_STARTSTOP BIT(27)
#define ETM_MODE_EXCL_KERN BIT(30)
#define ETM_MODE_EXCL_USER BIT(31)
#define ETMv4_MODE_ALL \
	(GENMASK(27, 0) | ETM_MODE_EXCL_KERN | ETM_MODE_EXCL_USER)

/*
 * TRCOSLSR.OSLM advertises the OS Lock model.
 * OSLM[2:0] = TRCOSLSR[4:3,0]
 *
 *	0b000 - Trace OS Lock is not implemented.
 *	0b010 - Trace OS Lock is implemented.
 *	0b100 - Trace OS Lock is not implemented, unit is controlled by PE OS Lock.
 */
#define ETM_OSLOCK_NI 0b000
#define ETM_OSLOCK_PRESENT 0b010
#define ETM_OSLOCK_PE 0b100

#define ETM_OSLSR_OSLM(oslsr) ((((oslsr) & GENMASK(4, 3)) >> 2) | (oslsr & 0x1))

/*
 * TRCDEVARCH Bit field definitions
 * Bits[31:21]	- ARCHITECT = Always Arm Ltd.
 *                * Bits[31:28] = 0x4
 *                * Bits[27:21] = 0b0111011
 * Bit[20]	- PRESENT,  Indicates the presence of this register.
 *
 * Bit[19:16]	- REVISION, Revision of the architecture.
 *
 * Bit[15:0]	- ARCHID, Identifies this component as an ETM
 *                * Bits[15:12] - architecture version of ETM
 *                *             = 4 for ETMv4
 *                * Bits[11:0] = 0xA13, architecture part number for ETM.
 */
#define ETM_DEVARCH_ARCHITECT_MASK GENMASK(31, 21)
#define ETM_DEVARCH_ARCHITECT_ARM ((0x4 << 28) | (0b0111011 << 21))
#define ETM_DEVARCH_PRESENT BIT(20)
#define ETM_DEVARCH_REVISION_SHIFT 16
#define ETM_DEVARCH_REVISION_MASK GENMASK(19, 16)
#define ETM_DEVARCH_REVISION(x) \
	(((x) & ETM_DEVARCH_REVISION_MASK) >> ETM_DEVARCH_REVISION_SHIFT)
#define ETM_DEVARCH_ARCHID_MASK GENMASK(15, 0)
#define ETM_DEVARCH_ARCHID_ARCH_VER_SHIFT 12
#define ETM_DEVARCH_ARCHID_ARCH_VER_MASK GENMASK(15, 12)
#define ETM_DEVARCH_ARCHID_ARCH_VER(x)               \
	(((x) & ETM_DEVARCH_ARCHID_ARCH_VER_MASK) >> \
	 ETM_DEVARCH_ARCHID_ARCH_VER_SHIFT)

#define ETM_DEVARCH_MAKE_ARCHID_ARCH_VER(ver)           \
	(((ver) << ETM_DEVARCH_ARCHID_ARCH_VER_SHIFT) & \
	 ETM_DEVARCH_ARCHID_ARCH_VER_MASK)

#define ETM_DEVARCH_ARCHID_ARCH_PART(x) ((x) & 0xfffUL)

#define ETM_DEVARCH_MAKE_ARCHID(major)               \
	((ETM_DEVARCH_MAKE_ARCHID_ARCH_VER(major)) | \
	 ETM_DEVARCH_ARCHID_ARCH_PART(0xA13))

#define ETM_DEVARCH_ARCHID_ETMv4x ETM_DEVARCH_MAKE_ARCHID(0x4)
#define ETM_DEVARCH_ARCHID_ETE ETM_DEVARCH_MAKE_ARCHID(0x5)

#define ETM_DEVARCH_ID_MASK                                     \
	(ETM_DEVARCH_ARCHITECT_MASK | ETM_DEVARCH_ARCHID_MASK | \
	 ETM_DEVARCH_PRESENT)
#define ETM_DEVARCH_ETMv4x_ARCH                                  \
	(ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETMv4x | \
	 ETM_DEVARCH_PRESENT)
#define ETM_DEVARCH_ETE_ARCH                                  \
	(ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETE | \
	 ETM_DEVARCH_PRESENT)

#define TRCSTATR_IDLE_BIT 0
#define TRCSTATR_PMSTABLE_BIT 1
#define ETM_DEFAULT_ADDR_COMP 0

#define TRCSSCSRn_PC BIT(3)

/* PowerDown Control Register bits */
#define TRCPDCR_PU BIT(3)

#define TRCACATR_EXLEVEL_SHIFT 8

/*
 * Exception level mask for Secure and Non-Secure ELs.
 * ETM defines the bits for EL control (e.g, TRVICTLR, TRCACTRn).
 * The Secure and Non-Secure ELs are always to gether.
 * Non-secure EL3 is never implemented.
 * We use the following generic mask as they appear in different
 * registers and this can be shifted for the appropriate
 * fields.
 */
#define ETM_EXLEVEL_S_APP BIT(0) /* Secure EL0		*/
#define ETM_EXLEVEL_S_OS BIT(1) /* Secure EL1		*/
#define ETM_EXLEVEL_S_HYP BIT(2) /* Secure EL2		*/
#define ETM_EXLEVEL_S_MON BIT(3) /* Secure EL3/Monitor	*/
#define ETM_EXLEVEL_NS_APP BIT(4) /* NonSecure EL0	*/
#define ETM_EXLEVEL_NS_OS BIT(5) /* NonSecure EL1	*/
#define ETM_EXLEVEL_NS_HYP BIT(6) /* NonSecure EL2	*/

/* access level controls in TRCACATRn */
#define TRCACATR_EXLEVEL_SHIFT 8

#define ETM_TRCIDR1_ARCH_MAJOR_SHIFT 8
#define ETM_TRCIDR1_ARCH_MAJOR_MASK (0xfU << ETM_TRCIDR1_ARCH_MAJOR_SHIFT)
#define ETM_TRCIDR1_ARCH_MAJOR(x) \
	(((x) & ETM_TRCIDR1_ARCH_MAJOR_MASK) >> ETM_TRCIDR1_ARCH_MAJOR_SHIFT)
#define ETM_TRCIDR1_ARCH_MINOR_SHIFT 4
#define ETM_TRCIDR1_ARCH_MINOR_MASK (0xfU << ETM_TRCIDR1_ARCH_MINOR_SHIFT)
#define ETM_TRCIDR1_ARCH_MINOR(x) \
	(((x) & ETM_TRCIDR1_ARCH_MINOR_MASK) >> ETM_TRCIDR1_ARCH_MINOR_SHIFT)
#define ETM_TRCIDR1_ARCH_SHIFT ETM_TRCIDR1_ARCH_MINOR_SHIFT
#define ETM_TRCIDR1_ARCH_MASK \
	(ETM_TRCIDR1_ARCH_MAJOR_MASK | ETM_TRCIDR1_ARCH_MINOR_MASK)

#define ETM_TRCIDR1_ARCH_ETMv4 0x4

/*
 * Driver representation of the ETM architecture.
 * The version of an ETM component can be detected from
 *
 * TRCDEVARCH	- CoreSight architected register
 *                - Bits[15:12] - Major version
 *                - Bits[19:16] - Minor version
 *
 * We must rely only on TRCDEVARCH for the version information. Even though,
 * TRCIDR1 also provides the architecture version, it is a "Trace" register
 * and as such must be accessed only with Trace power domain ON. This may
 * not be available at probe time.
 *
 * Now to make certain decisions easier based on the version
 * we use an internal representation of the version in the
 * driver, as follows :
 *
 * ETM_ARCH_VERSION[7:0], where :
 *      Bits[7:4] - Major version
 *      Bits[3:0] - Minro version
 */
#define ETM_ARCH_VERSION(major, minor) \
	((((major) & 0xfU) << 4) | (((minor) & 0xfU)))
#define ETM_ARCH_MAJOR_VERSION(arch) (((arch) >> 4) & 0xfU)
#define ETM_ARCH_MINOR_VERSION(arch) ((arch) & 0xfU)

#define ETM_ARCH_V4 ETM_ARCH_VERSION(4, 0)
#define ETM_ARCH_ETE ETM_ARCH_VERSION(5, 0)

/* Interpretation of resource numbers change at ETM v4.3 architecture */
#define ETM_ARCH_V4_3 ETM_ARCH_VERSION(4, 3)

#endif
